package com.xuzz.study.thread.threadpool;

import com.xuzz.study.datastructure.BlockingQueue;

import java.util.HashSet;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolExecutor implements ExecutorService {

    private volatile ThreadFactory threadFactory;
    private  BlockingQueue<Runnable> workQueue;
    private volatile int corePoolSize;
    private volatile int maximumPoolSize;

    private final HashSet<Worker> workers = new HashSet<Worker>();
    private static final AtomicInteger ctl = new AtomicInteger(0);

    ThreadPoolExecutor(int corePoolSize,
                       int maximumPoolSize,
                        BlockingQueue<Runnable> workQueue,
                ThreadFactory threadFactory)
    {
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.threadFactory = threadFactory;

    }

    @Override
    public void execute(Runnable command) {
        //jdk中的实现，是高3位标识线程池状态，其他位数标识线程个数。然后通过位运算
        //标识位是29位（COUNT_BITS = Integer.SIZE - 3;），高3位是状态，低19位是个数
        // private static int runStateOf(int c)     { return c & ~CAPACITY; }
        // private static int workerCountOf(int c)  { return c & CAPACITY; }
        //线程池的状态：RUNNING TIDING STOP SHUTDOWN TERMINATED
        if(ctl.get()<this.corePoolSize)
        {
            //小于core size，则直接创建线程执行
            if(addWorker(command,true))
            {
                return;
            }
        }

        //否则加入到队列中
        if(workQueue.offer(command))
        {

        }
        else
        {
            //如果加入到队列中失败，则说明队列已满，那么创建线程执行

            if(!addWorker(command,false))
            {
                System.out.println("任务" + command + "被线程池拒绝");
            }
        }

    }

    private boolean addWorker(Runnable task,boolean core)
    {
        int c = ctl.get();
        if(c>(core?corePoolSize:maximumPoolSize))
        {
            return false;
        }

        ctl.compareAndSet(c,c+1);

        //创建一个线程，并立即执行
        Worker worker = new Worker(task);
        //拿到线程
        Thread t = worker.thread;
        workers.add(worker);
        //立即执行
        t.start();
        return true;
    }

    final class Worker implements Runnable
    {
        Thread thread;
        Runnable firstTask;

        Worker(Runnable task)
        {
            //注意，这里线程指向的是this，而不是task
            this.thread =threadFactory.newThread(this);
            this.firstTask = task;
        }

        @Override
        public void run() {
            Runnable task = firstTask;
            while(null!=task || null!=(task=workQueue.take()))
            {
                task.run();
                task = null;
            }
        }
    }
}
